package com.loto.webapp.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;

import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

public class Files {
	private final static String CONFIG_CACHE_NAME = "configfile";
	private final static String CONFIG_FILE_PATH = "/configfile";

	private static CacheManager cacheManager = CacheManager.create();

	public static void setMenuCache(HttpServletRequest request, String username) {
		Document document = null;
		String menuFilename = username + "MenuConfig";
		String cachename = username + "-" + CONFIG_CACHE_NAME;
		try {
			cacheManager.addCache(CONFIG_CACHE_NAME);
			document = getConfigFile(request, menuFilename);

			Cache ca = cacheManager.getCache(CONFIG_CACHE_NAME);
			ca.put(new Element(cachename, document));
		} catch (Exception e) {
			e.getStackTrace();
		}
	}

	public static Document getMenuXml(HttpServletRequest request,
			String username) {
		Document document = null;
		boolean isCached = true;
		String menuFilename = username + "MenuConfig";
		String cachename = username + "-" + CONFIG_CACHE_NAME;
		try {
			Cache cache = cacheManager.getCache(CONFIG_CACHE_NAME);
			if (cache != null) {
				Element element = cache.get(cachename);
				if (element == null) {
					isCached = false;
				} else {
					document = (Document) element.getValue();
					if (document == null) {
						isCached = false;
					}
				}
				if (!isCached) {
					document = getConfigFile(request, menuFilename);
					//cache.put(new Element(cachename, document));
				}
			} else {
				//cacheManager.addCache(CONFIG_CACHE_NAME);
				document = getConfigFile(request, menuFilename);

				/*Cache ca = cacheManager.getCache(CONFIG_CACHE_NAME);
				ca.put(new Element(cachename, document));*/

			}
		} catch (Exception e) {
			return null;
		}
		return document;
	}

	public static Document getBaseMenuXml(HttpServletRequest request) {
		Document document = null;
		boolean isCached = true;
		String menuFilename = "baseMC";
		String cachename = menuFilename + "-" + CONFIG_CACHE_NAME;
		try {
			Cache cache = cacheManager.getCache(CONFIG_CACHE_NAME);
			if (cache != null) {
				Element element = cache.get(cachename);
				if (element == null) {
					isCached = false;
				} else {
					document = (Document) element.getValue();
					if (document == null) {
						isCached = false;
					}
				}
				if (!isCached) {
					document = getConfigFile(request, menuFilename);
					cache.put(new Element(cachename, document));
				}
			} else {
				cacheManager.addCache(CONFIG_CACHE_NAME);
				document = getConfigFile(request, menuFilename);
				Cache ca = cacheManager.getCache(CONFIG_CACHE_NAME);
				ca.put(new Element(cachename, document));
			}
		} catch (Exception e) {
			return null;
		}
		return document;
	}

	public static Document getRelatedXml(HttpServletRequest request) {
		Document document = null;
		boolean isCached = true;
		String filename = "pageRelated";
		String cachename = "related" + CONFIG_CACHE_NAME;
		try {
			Cache cache = cacheManager.getCache(CONFIG_CACHE_NAME);
			if (cache != null) {
				Element element = cache.get(cachename);
				if (element == null) {
					isCached = false;
				} else {
					document = (Document) element.getValue();
					if (document == null) {
						isCached = false;
					}
				}
				if (!isCached) {
					document = getConfigFile(request, filename);
					cache.put(new Element(cachename, document));
				}
			} else {
				cacheManager.addCache(CONFIG_CACHE_NAME);
				document = getConfigFile(request, filename);
				Cache ca = cacheManager.getCache(CONFIG_CACHE_NAME);
				ca.put(new Element(cachename, document));
			}
		} catch (Exception e) {
			return null;
		}
		return document;
	}

	public static boolean buildConfigFile(HttpServletRequest request,
			String[] rights, String user) throws ParserConfigurationException {
		boolean isSuc = false;
		Document doc = getBaseMenuXml(request);
		org.w3c.dom.Element rootElement = doc.getDocumentElement();
		NodeList list = rootElement.getElementsByTagName("Menu");
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document document = builder.newDocument();

		org.w3c.dom.Element menuConfig = document.createElement("MenuConfig");
		org.w3c.dom.Element menuList = document.createElement("MenuList");
		boolean hadChild = false;
		for (int i = 0; i < list.getLength(); i++) {
			hadChild = false;
			org.w3c.dom.Element menu = document.createElement("Menu");

			org.w3c.dom.Element element = (org.w3c.dom.Element) list.item(i);
			menu.setAttribute("ID", element.getAttribute("ID"));
			menu.setAttribute("Name", element.getAttribute("Name"));
			menu.setAttribute("Url", element.getAttribute("Url"));

			NodeList sublist = element.getElementsByTagName("ChildMenu");
			for (int j = 0; j < sublist.getLength(); j++) {
				org.w3c.dom.Element subelement = (org.w3c.dom.Element) sublist
						.item(j);
				for (String s : rights) {
					if (s.equals(subelement.getAttribute("ID"))) {
						hadChild = true;
						org.w3c.dom.Element childMenu = document
								.createElement("ChildMenu");
						childMenu.setAttribute("ID",
								subelement.getAttribute("ID"));
						childMenu.setAttribute("Name",
								subelement.getAttribute("Name"));
						childMenu.setAttribute("Url",
								subelement.getAttribute("Url"));
						menu.appendChild(childMenu);
						break;
					}
				}
			}
			if (hadChild || element.getAttribute("ID").equals("1"))
				menuList.appendChild(menu);
		}

		menuConfig.appendChild(menuList);
		document.appendChild(menuConfig);

		String filename = user + "MenuConfig";

		try {
			TransformerFactory tf = TransformerFactory.newInstance();
			Transformer transformer = tf.newTransformer();
			DOMSource source = new DOMSource(document);
			transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
			// transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			OutputStreamWriter pw = new OutputStreamWriter(
					new FileOutputStream(request.getSession()
							.getServletContext().getRealPath(CONFIG_FILE_PATH)
							+ "/" + filename + ".xml"), "utf-8");
			StreamResult result = new StreamResult(pw);
			transformer.transform(source, result);
			cleanCache(user);
			isSuc = true;
		} catch (TransformerException mye) {
			isSuc = false;
			mye.printStackTrace();
		} catch (IOException exp) {
			isSuc = false;
			exp.printStackTrace();
		}
		return isSuc;
	}

	private static Document getConfigFile(HttpServletRequest request,
			String fileName) {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		try {
			DocumentBuilder builder = factory.newDocumentBuilder();
			return builder.parse(new File(request.getSession()
					.getServletContext().getRealPath(CONFIG_FILE_PATH)
					+ "/" + fileName + ".xml"));			
		} catch (Exception e) {
			return null;
		}
	}

	public static void cleanCache(String username) {
		String menuFilename = username + "MenuConfig";
		String cachename = menuFilename + "-" + CONFIG_CACHE_NAME;
		try {
			Cache cache = cacheManager.getCache(CONFIG_CACHE_NAME);
			if (cache != null) {
				Element element = cache.get(cachename);
				if (element != null) {
					cache.remove(cachename);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
